﻿using System;
using System.Collections.Generic;
using Assist;
using Autodesk.Revit.DB;
using YJKRGeometry;
using SectionSignAndFilled.StairsRoomSection.DataDefine;
using SectionSignAndFilled.StairsRoomSection.ElementPacket;

namespace SectionSignAndFilled.StairsRoomSection.Kit.CutLine
{
	internal class LayerCutLineGetter : CutLineGetter
	{
		public override bool GetCutLines(SectionViewData ViewInfoRay, ElementObject elemObj)
		{
			List<Curve> list = new List<Curve>();
			if (!(elemObj is LayerObject))
			{
				return false;
			}
			LayerObject layerObject = elemObj as LayerObject;
			SectionViewData sectionViewData;
			base.TransformViewData(elemObj, ViewInfoRay, out sectionViewData);
			XYZ endPoint = sectionViewData.m_SecLine.GetEndPoint(0);
			XYZ endPoint2 = sectionViewData.m_SecLine.GetEndPoint(1);
			XYZ origin = (endPoint + endPoint2) / 2.0;
			XYZ viewDir = sectionViewData.m_viewDir;
			List<Solid> list2 = new List<Solid>();
			CommonFun.GetSolidFromABeam(list2, elemObj.SelfElem.UseElement);
			Plane planeCut = RevitVersionFuncs.CreatePlanByNormalAndOrigin(viewDir, origin);
			List<Solid> list3 = new List<Solid>();
			for (int i = 0; i < list2.Count; i++)
			{
				Solid solid = list2[i];
				solid = CommonFun.CutWithHalfSpace(solid, sectionViewData, planeCut, true);
				list3.Add(solid);
			}
			if (sectionViewData.m_viewDir.IsAlmostEqualTo(XYZ.BasisZ) && elemObj.SelfElem.UseElement is Wall)
			{
				Wall wall = elemObj.SelfElem.UseElement as Wall;
				Curve curve = (wall.Location as LocationCurve).Curve;
				if (curve is Arc)
				{
					Curve lastLayerCutCurve = layerObject.GetLastLayerCutCurve(layerObject.m_IndexPos, endPoint.Z);
					Curve lastLayerCutCurve2 = layerObject.GetLastLayerCutCurve(layerObject.m_IndexPos - 1, endPoint.Z);
					list.Add(lastLayerCutCurve);
					Curve item = Line.CreateBound(lastLayerCutCurve.GetEndPoint(1), lastLayerCutCurve2.GetEndPoint(1));
					list.Add(item);
					list.Add(lastLayerCutCurve2);
					Curve item2 = Line.CreateBound(lastLayerCutCurve2.GetEndPoint(0), lastLayerCutCurve.GetEndPoint(0));
					list.Add(item2);
					return true;
				}
			}
			List<Solid> cutSolid = this.GetCutSolid(sectionViewData, elemObj, list3);
			if (cutSolid == null)
			{
				return true;
			}
			this.GetFaceEdage(cutSolid, planeCut, ref list);
			list = CommonFun.TranCurve(list, layerObject.GetLinkTran());
			elemObj.m_lstCutLine.AddRange(list);
			return true;
		}

		public List<Solid> GetCutSolid(SectionViewData ViewInfo, ElementObject elemObj, List<Solid> solidsOneCut)
		{
			List<Solid> list = new List<Solid>();
			LayerObject layerObject = elemObj as LayerObject;
			int maxLayerIndex = layerObject.m_MaxLayerIndex;
			int minLayerIndex = layerObject.m_MinLayerIndex;
			int indexPos = layerObject.m_IndexPos;
			Plane lastLayerCutPlane = (layerObject.m_parentObj as ComLayerObject).GetLastLayerCutPlane(indexPos, ViewInfo.m_SecLine);
			Plane plane = (layerObject.m_parentObj as ComLayerObject).GetLastLayerCutPlane(indexPos - 1, ViewInfo.m_SecLine);
			if (lastLayerCutPlane == null && plane == null)
			{
				return null;
			}
			for (int i = 0; i < solidsOneCut.Count; i++)
			{
				Solid solid = solidsOneCut[i];
				if (indexPos == minLayerIndex)
				{
					solid = CommonFun.CutWithHalfSpace(solid, ViewInfo, lastLayerCutPlane, false);
				}
				else if (indexPos > minLayerIndex && indexPos < maxLayerIndex)
				{
					plane = RevitVersionFuncs.CreatePlanByNormalAndOrigin(-plane.Normal, plane.Origin);
					if (plane != null)
					{
						solid = CommonFun.CutWithHalfSpace(solid, ViewInfo, plane, false);
					}
					if (solid != null)
					{
						solid = CommonFun.CutWithHalfSpace(solid, ViewInfo, lastLayerCutPlane, false);
					}
				}
				else if (indexPos == maxLayerIndex)
				{
					plane = RevitVersionFuncs.CreatePlanByNormalAndOrigin(-plane.Normal, plane.Origin);
					if (plane != null)
					{
						solid = CommonFun.CutWithHalfSpace(solid, ViewInfo, plane, false);
					}
				}
				if (solid != null)
				{
					list.Add(solid);
				}
			}
			return list;
		}

		private void GetFaceEdage(List<Solid> lstSolid, Plane planeCut, ref List<Curve> lstCutLines)
		{
			for (int i = 0; i < lstSolid.Count; i++)
			{
				Solid solid = lstSolid[i];
				for (int j = 0; j < solid.Faces.Size; j++)
				{
					Face face = solid.Faces.get_Item(j);
					XYZ xyz = XYZ.Zero;
					BoundingBoxUV boundingBox = face.GetBoundingBox();
					UV uv = (boundingBox.Min + boundingBox.Max) / 2.0;
					XYZ xyz2 = face.Evaluate(uv);
					xyz = (xyz2 - planeCut.Origin).Normalize();
					double val = planeCut.Normal.DotProduct(xyz);
					if (Geometry.IsEqual(val, 0.0))
					{
						foreach (object obj in face.EdgeLoops)
						{
							EdgeArray edgeArray = (EdgeArray)obj;
							foreach (object obj2 in edgeArray)
							{
								Edge edge = (Edge)obj2;
								lstCutLines.Add(edge.AsCurve());
							}
						}
					}
				}
			}
		}
	}
}
